package com.ruoyi.common.utils;

import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

/**
 * 解密工具类
 *
 * @Author duyongmeng
 * @Time 2020/11/10
 */
@Component
public class DecodeUtils {

    /**
     * base64解密
     *
     * @param s 密文
     * @return 解密后的数据
     */
    byte[] fromBase64(String s) {
        byte[] b = null;
        if (s != null) {
            Base64.Decoder decoder = Base64.getDecoder();
            b = decoder.decode(s.getBytes());
        }
        return b;
    }

    /**
     * 解密微信用户的个人信息
     *
     * @param encryptedData 密文数据
     * @param iv            偏移量
     * @param sessionKey    密钥
     * @return 解密后的数据
     * @throws Exception 有可能出现的异常
     */
    @RequestMapping("decodeUserInfo")
    @ResponseBody
    public JSONObject decrypt(String encryptedData, String iv, String sessionKey) throws Exception {
        String jsonStr;
        JSONObject jsonObject;
        try {
            //小程序加密数据解密算法
            // https://developers.weixin.qq.com/miniprogram/dev/api/signature.html#wxchecksessionobject
            // 1.对称解密的目标密文为 Base64_Decode(encryptedData)。
            //2.对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
            //3.对称解密算法初始向量 为Base64_Decode(iv)，其中iv由数据接口返回。
            System.out.println(1);
            byte[] encryptedByte = fromBase64(encryptedData);
            byte[] sessionKeyByte = fromBase64(sessionKey);
            byte[] ivByte = fromBase64(iv);
            // 以下为AES-128-CBC解密算法
            SecretKeySpec skeySpec = new SecretKeySpec(sessionKeyByte, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(ivByte);
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);
            byte[] original = cipher.doFinal(encryptedByte);
            jsonStr = new String(original);
            jsonObject = JSONObject.parseObject(jsonStr);
        } catch (Exception ex) {
            throw new Exception("Illegal Buffer");
        }
        return jsonObject;
    }
}
